package textfileproces;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

/**
 * @author manuel
 * <p>
 * This class is the common part to classes that read a file and writes it 
 * performing a transformation.<p>
 * It ensures that the input file exists and deletes the
 * output file before the transformation, if it exists.
 */
public abstract class FileConversion {

    // Constants
	protected final String DEFAULT_CHARSET_NAME = "UTF-8";
	
	// Attributes
	protected int status = 0;

	protected String inputFileName;
	protected String outputFileName;

	protected Path inputPath;
	protected Path outputPath;

	protected Charset charset = null;

	protected BufferedReader reader;
	protected BufferedWriter writer;
	
	// Constructor
    /**
     * The constructor sets the name of input and output files 
     * and deletes the output file if it exists.
     * @param inputFileName. <code>String</code>
     * @param outputFileName. <code>String</code>
     * @throws IOException when the input file does not exist or the output file
     * can not be removed if it exists. 
     */
    public FileConversion(String inputFileName, String outputFileName) 
    		throws IOException {
    	this.inputFileName = inputFileName;
    	this.outputFileName = outputFileName;
		inputPath = Paths.get(inputFileName);
		if (!Files.exists(inputPath, LinkOption.NOFOLLOW_LINKS)) {
			status = -1;
			throw new IOException("Input file " + inputFileName + 
					" does not exits.");
		}
		outputPath = Paths.get(outputFileName);
		Files.deleteIfExists(outputPath);
    }

    // Methods
    /** Performs the operation creating a new file called 'outputFileName'.
     * This method must be different in each extending class. */
	public abstract void run() throws IOException;
	
	public void createReaderAndWriter() throws IOException {
		charset = charset == null ? getCharset() : charset;
		if (reader == null) {
			reader = Files.newBufferedReader(inputPath, charset);
		}
		if (writer == null) {
			writer = Files.newBufferedWriter(outputPath, charset,
					StandardOpenOption.CREATE_NEW);
		}
	}
	
	/**
	 * @return The <code>Charset</code>; if it does not exists 
	 *  it creates a default one.
	 */
	public Charset getCharset() {
		if (charset == null) {
			charset = Charset.forName(DEFAULT_CHARSET_NAME);
		}
		return charset;
	}
	
	public void setCharset(Charset charset) {
		this.charset = charset;
	}
	
	public int getStatus() {
		return status;
	}
	
	public BufferedReader getReader() {
		return reader;
	}
	
	public BufferedWriter getWriter() {
		return writer;
	}
	
}
